#include "IRremoteESP8266.h"
#include <vector>
#include <sstream>
#include <EEPROM.h>

#define EEPROM_SIZE 512 // ESP8266 EEPROM 大小，单位字节
#define DATA_SIZE 100   // 数据块大小，根据实际需要设置
#define EEPROM_START_ADDR 0

struct DataBlock
{
    int16_t type_index;
    byte payload[DATA_SIZE];
};
const decode_type_t decodeTypeList[] = {
    decode_type_t::AIRTON,               // -------- // 艾力顿
    decode_type_t::AIRWELL,              // --------// 欧威尔
    decode_type_t::AIWA_RC_T501,         // AIWA
    decode_type_t::AMCOR,                // -------- // 艾玛克
    decode_type_t::ARGO,                 // ARGO
    decode_type_t::ARRIS,                // -------- // 艾锐势
    decode_type_t::BOSCH144,             // -------- // 博世
    decode_type_t::BOSE,                 // -------- // BOSE（博士）
    decode_type_t::CARRIER_AC,           // -------- // 开利
    decode_type_t::CARRIER_AC128,        // -------- // 开利
    decode_type_t::CARRIER_AC40,         // -------- // 开利
    decode_type_t::CARRIER_AC64,         // -------- // 开利
    decode_type_t::CARRIER_AC84,         // -------- // 开利
    decode_type_t::CLIMABUTLER,          // climabutter
    decode_type_t::COOLIX,               // coolix
    decode_type_t::COOLIX48,             // coolix
    decode_type_t::CORONA_AC,            // corona
    decode_type_t::DAIKIN,               // -------- // 大金
    decode_type_t::DAIKIN128,            // -------- // 大金
    decode_type_t::DAIKIN152,            // -------- // 大金
    decode_type_t::DAIKIN160,            // -------- // 大金
    decode_type_t::DAIKIN176,            // -------- // 大金
    decode_type_t::DAIKIN2,              // -------- // 大金
    decode_type_t::DAIKIN200,            // -------- // 大金
    decode_type_t::DAIKIN216,            // -------- // 大金
    decode_type_t::DAIKIN312,            // -------- // 大金
    decode_type_t::DAIKIN64,             // -------- // 大金
    decode_type_t::DELONGHI_AC,          // -------- // delonghi（德龙）
    decode_type_t::DENON,                // denon
    decode_type_t::DISH,                 // dish
    decode_type_t::DOSHISHA,             // dish
    decode_type_t::ECOCLIM,              // ecoclim
    decode_type_t::ELECTRA_AC,           // electra
    decode_type_t::ELITESCREENS,         // elitescreens
    decode_type_t::EPSON,                // -------- // 爱普生
    decode_type_t::FUJITSU_AC,           // -------- // 富士通
    decode_type_t::GICABLE,              // gicable
    decode_type_t::GLOBALCACHE,          // globalcache
    decode_type_t::GOODWEATHER,          // goodweather
    decode_type_t::GORENJE,              // gorenje
    decode_type_t::GREE,                 // -------- // 格力
    decode_type_t::HAIER_AC,             // -------- // 海尔
    decode_type_t::HAIER_AC160,          // -------- // 海尔
    decode_type_t::HAIER_AC176,          // -------- // 海尔
    decode_type_t::HAIER_AC_YRW02,       // -------- // 海尔
    decode_type_t::HITACHI_AC,           // -------- // 日立
    decode_type_t::HITACHI_AC1,          // -------- // 日立
    decode_type_t::HITACHI_AC2,          // -------- // 日立
    decode_type_t::HITACHI_AC264,        // -------- // 日立
    decode_type_t::HITACHI_AC296,        // -------- // 日立
    decode_type_t::HITACHI_AC3,          // -------- // 日立
    decode_type_t::HITACHI_AC344,        // -------- // 日立
    decode_type_t::HITACHI_AC424,        // -------- // 日立
    decode_type_t::INAX,                 // inax
    decode_type_t::JVC,                  // jvc
    decode_type_t::KELON,                // -------- // 科龙
    decode_type_t::KELON168,             // -------- // 科龙
    decode_type_t::KELVINATOR,           // -------- // 科龙
    decode_type_t::LASERTAG,             // lasertag
    decode_type_t::LEGOPF,               // legopf
    decode_type_t::LG,                   // -------- // lg
    decode_type_t::LG2,                  // -------- // lg
    decode_type_t::LUTRON,               // -------- // 路创
    decode_type_t::MAGIQUEST,            // magiquest
    decode_type_t::METZ,                 // -------- // 美兹
    decode_type_t::MIDEA,                // -------- // 美的
    decode_type_t::MIDEA24,              // -------- // 美的
    decode_type_t::MILESTAG2,            // milestag2
    decode_type_t::MIRAGE,               // mirage
    decode_type_t::MITSUBISHI,           // -------- // 三菱
    decode_type_t::MITSUBISHI112,        // -------- // 三菱
    decode_type_t::MITSUBISHI136,        // -------- // 三菱
    decode_type_t::MITSUBISHI2,          // -------- // 三菱
    decode_type_t::MITSUBISHI_AC,        // -------- // 三菱
    decode_type_t::MITSUBISHI_HEAVY_152, // -------- // 三菱
    decode_type_t::MITSUBISHI_HEAVY_88,  // -------- // 三菱
    decode_type_t::MULTIBRACKETS,        // multibrackets
    decode_type_t::MWM,                  // mwm
    decode_type_t::NEC,                  // nec
    decode_type_t::NEC_LIKE,             // nec
    decode_type_t::NEOCLIMA,             // neoclima
    decode_type_t::NIKAI,                // nikai
    decode_type_t::PANASONIC,            // -------- // 松下
    decode_type_t::PANASONIC_AC,         // -------- // 松下
    decode_type_t::PANASONIC_AC32,       // -------- // 松下
    decode_type_t::PIONEER,              // pioneer
    decode_type_t::PRONTO,               // pronto
    decode_type_t::RAW,                  // raw
    decode_type_t::RC5,                  // rc5
    decode_type_t::RC5X,                 // rc5x
    decode_type_t::RC6,                  // rc6
    decode_type_t::RCMM,                 // rcmm
    decode_type_t::RHOSS,                // -------- // 乐士
    decode_type_t::SAMSUNG,              // -------- // 三星
    decode_type_t::SAMSUNG36,            // -------- // 三星
    decode_type_t::SAMSUNG_AC,           // -------- // 三星
    decode_type_t::SANYO,                // -------- // 三洋
    decode_type_t::SANYO_AC,             // -------- // 三洋
    decode_type_t::SANYO_AC152,          // -------- // 三洋
    decode_type_t::SANYO_AC88,           // -------- // 三洋
    decode_type_t::SANYO_LC7461,         // -------- // 三洋
    decode_type_t::SHARP,                // -------- // 夏普
    decode_type_t::SHARP_AC,             // -------- // 夏普
    decode_type_t::SHERWOOD,             // sherwood
    decode_type_t::SONY,                 // -------- // 索尼
    decode_type_t::SONY_38K,             // -------- // 索尼
    decode_type_t::SYMPHONY,             // symphony
    decode_type_t::TCL96AC,              // -------- // tcl
    decode_type_t::TCL112AC,             // -------- // TCL
    decode_type_t::TECHNIBEL_AC,         // technibel
    decode_type_t::TECO,                 // -------- // teco（东元）
    decode_type_t::TEKNOPOINT,           // teknopoint
    decode_type_t::TOSHIBA_AC,           // -------- // 东芝
    decode_type_t::TOTO,                 // -------- // toto（东陶）
    decode_type_t::TRANSCOLD,            // transcold
    decode_type_t::TROTEC,               // -------- // trotec（卓泰克）
    decode_type_t::TROTEC_3550,          // -------- // trotec（卓泰克）
    decode_type_t::TRUMA,                // -------- // truma（特鲁马）
    decode_type_t::VESTEL_AC,            // vestel
    decode_type_t::VOLTAS,               // voltas
    decode_type_t::WHIRLPOOL_AC,         // -------- // whirlpool（惠而浦）
    decode_type_t::WHYNTER,              // whynter
    decode_type_t::WOWWEE,               // wowwee
    decode_type_t::XMP,                  // xmp
    decode_type_t::YORK,                 // -------- // york（约克）
    decode_type_t::ZEPEAL,               // zepeal
    decode_type_t::UNKNOWN,
    decode_type_t::UNUSED,
};
// 计算 141-16=
std::vector<uint16_t> ac_gree = {40};                                       // 格力
std::vector<uint16_t> ac_midea = {65, 66};                                  // 美的
std::vector<uint16_t> ac_haier = {41, 42, 43, 44};                          // 海尔
std::vector<uint16_t> ac_tcl = {107, 108};                                  // 踢死矮欧
std::vector<uint16_t> ac_panasonic = {82, 83, 84};                          // 松下
std::vector<uint16_t> ac_samsung = {93, 94, 95};                            // 三星
std::vector<uint16_t> ac_hitachi = {45, 46, 47, 48, 49, 50, 51, 52};        // 日立
std::vector<uint16_t> ac_sanyo = {96, 97, 98, 99, 100};                     // 三洋
std::vector<uint16_t> ac_sony = {104, 105};                                 // 索尼
std::vector<uint16_t> ac_sharp = {101, 102};                                // 夏普
std::vector<uint16_t> ac_toshiba = {112};                                   // 东芝
std::vector<uint16_t> ac_rhoss = {92};                                      // 乐士
std::vector<uint16_t> ac_mitsubishi = {69, 70, 71, 72, 73, 74, 75};         // 三菱
std::vector<uint16_t> ac_kelon = {55, 56};                                  // 科龙
std::vector<uint16_t> ac_lg = {60, 61};                                     // 矮欧机
std::vector<uint16_t> ac_daikin = {17, 18, 19, 20, 21, 22, 23, 24, 25, 26}; // 大金
std::vector<uint16_t> ac_karrier = {8, 9, 10, 11, 12, 57};                  // 开利
std::vector<uint16_t> ac_whirlpool = {120};                                 // 惠而浦
std::vector<uint16_t> ac_epson = {34};                                      // 爱普生
std::vector<uint16_t> ac_fujitsu = {35};                                    // 富士通
std::vector<uint16_t> ac_airton = {0};                                      // 艾力顿
std::vector<uint16_t> ac_airwell = {1};                                     // 欧威尔
std::vector<uint16_t> ac_bosch = {6};                                       // 博世
std::vector<uint16_t> ac_bose = {7};                                        // 爆死
std::vector<uint16_t> ac_delonghi = {27};                                   // 德龙
std::vector<uint16_t> ac_lutron = {62};                                     // 路创
std::vector<uint16_t> ac_metz = {64};                                       // 美兹
std::vector<uint16_t> ac_toto = {113};                                      // 东陶
std::vector<uint16_t> ac_york = {124};                                      // 约克
std::vector<uint16_t> ac_amcor = {3};                                       // 艾玛克
std::vector<uint16_t> ac_arris = {5};                                       // 艾锐势
std::vector<uint16_t> ac_trotec = {115, 116};                               // 卓泰克
std::vector<uint16_t> ac_truma = {117};                                     // 特鲁马
std::vector<uint16_t> ac_teco = {110};
std::vector<uint16_t> ac_mirage = {68};                                                                                                                                                                                                       // 伊莱克斯
std::vector<uint16_t> ac_other = {126, 127, 2, 4, 13, 14, 15, 16, 28, 29, 30, 31, 32, 33, 36, 37, 38, 39, 53, 54, 58, 59, 63, 67, 76, 77, 78, 79, 80, 81, 85, 86, 87, 88, 89, 90, 91, 103, 106, 109, 111, 114, 118, 119, 121, 122, 123, 125}; // 其它

std::vector<std::vector<uint16_t>> ac_brands = {
    ac_gree,
    ac_midea,
    ac_haier,
    ac_tcl,
    ac_panasonic,
    ac_samsung,
    ac_hitachi,
    ac_sanyo,
    ac_sony,
    ac_sharp,
    ac_toshiba,
    ac_rhoss,
    ac_mitsubishi,
    ac_kelon,
    ac_lg,
    ac_daikin,
    ac_karrier,
    ac_whirlpool,
    ac_epson,
    ac_fujitsu,
    ac_airton,
    ac_airwell,
    ac_bosch,
    ac_bose,
    ac_delonghi,
    ac_lutron,
    ac_metz,
    ac_toto,
    ac_york,
    ac_amcor,
    ac_arris,
    ac_trotec,
    ac_truma,
    ac_teco,
    ac_mirage,
    ac_other};

String ac_brands_str[] = {
    "gree",
    "midea",
    "haier",
    "tcl",
    "panasonic",
    "samsung",
    "hitachi",
    "sanyo",
    "sony",
    "sharp",
    "toshiba",
    "rhoss",
    "mitsubishi",
    "kelon",
    "lg",
    "daikin",
    "karrier",
    "whirlpool",
    "epson",
    "fujitsu",
    "airton",
    "airwell",
    "bosch",
    "bose",
    "delonghi",
    "lutron",
    "metz",
    "toto",
    "york",
    "amcor",
    "arris",
    "trotec",
    "truma",
    "teco",
    "mirage",
    "other"};

void splitCommand(String &cmd, String parts[], const char *delimiter = "#")
{
    const int MAX_PARTS = 10;
    int pos = 0;
    int partsCount = 0;
    String currentPart;

    // 分割字符串
    while ((pos = cmd.indexOf(delimiter)) != -1 && partsCount < MAX_PARTS)
    {
        if (pos > 0)
        { // 避免第一个字符是'#'的情况
            currentPart = cmd.substring(0, pos);
            parts[partsCount++] = currentPart;
        }
        cmd = cmd.substring(pos + 1); // 移除已处理的部分
    }

    // 处理最后一个部分
    if (!cmd.isEmpty())
    {
        parts[partsCount++] = cmd;
    }
}

int findIndexByBrand(String &brand)
{
    int index = -1;
    for (size_t i = 0; i < sizeof(ac_brands_str) / sizeof(ac_brands_str[0]); ++i)
    {
        if (ac_brands_str[i] == brand)
        {
            index = i;
            break;
        }
    }
    return index;
}

bool isNumber(String str)
{
    for (size_t i = 0; i < str.length(); i++)
    {
        if (!isdigit(str[i]))
        {
            return false; // 只要有一个字符不是数字就返回false
        }
    }
    return true; // 所有字符都是数字
}

bool array_find(const std::vector<uint16_t> &array, uint16_t index)
{
    if (array.empty())
        return false;
    return std::find(array.begin(), array.end(), index) != array.end();
}

int16_t find_ac_index(size_t group_index, std::vector<uint16_t> &invalid_indexs)
{
    if (group_index >= ac_brands.size())
    {
        return -1;
    }
    const std::vector<uint16_t> &group = ac_brands[group_index];

    uint16_t index = 0;
    int16_t type_index = -1;
    while (index < group.size())
    {
        if (!array_find(invalid_indexs, group[index]))
        {
            type_index = group[index];
            break;
        }
        index++;
    }
    return type_index;
}

void clearData()
{
    DataBlock db;
    db.type_index = 0;
    for (int i = 0; i < DATA_SIZE; i++)
    {
        db.payload[i] = i;
    }

    // 写入数据到EEPROM
    for (int i = 0; i < EEPROM_SIZE; i++)
    {
        EEPROM.write(i, 0); // 初始化EEPROM全部为0
    }
    EEPROM.put(EEPROM_START_ADDR, db); // 写入数据块
}

void writeData(const int16_t index, const char *payload)
{
    EEPROM.begin(EEPROM_SIZE);
    DataBlock db;
    EEPROM.get(0, db);
    db.type_index = index;
    for (size_t i = 0; i < strlen(payload); ++i)
    {
        db.payload[i] = static_cast<uint8_t>(payload[i]);
    }
    for (int i = 0; i < EEPROM_SIZE; i++)
    {
        EEPROM.write(i, 0); // 初始化EEPROM全部为0
    }

    EEPROM.put(EEPROM_START_ADDR, db);
    EEPROM.commit();
    EEPROM.end();
}
void readData(int16_t &index, char *&payload)
{
    EEPROM.begin(EEPROM_SIZE);
    DataBlock db;
    EEPROM.get(0, db);
    index = db.type_index;
    payload = (char *)(db.payload);
    EEPROM.end();
}
